Skip to content

feat: IAS token flow with tenant host resolution#1971

Open
NiklasHerrmann21 wants to merge 7 commits into
mainfrom
feature/ias-token-flow-extension
Open

feat: IAS token flow with tenant host resolution#1971
NiklasHerrmann21 wants to merge 7 commits into
mainfrom
feature/ias-token-flow-extension

Conversation

@NiklasHerrmann21

Copy link
Copy Markdown
Contributor

Summary

Adds a multi-tenant-capable IAS token flow that resolves the correct subscriber token endpoint at runtime via the BTP tenant API, instead of hard-coding the provider's IAS host. Resolved subdomains are cached with a configurable Caffeine cache.

  • New IasTenantHostResolver queries /sap/rest/tenantLoginInfo?id={tenantId} on the BTP tenant API and extracts the subscriber's IAS subdomain from the returned token_endpoint.
  • IasTokenFlows integrates the resolver: when an app_tid is supplied, the configured IAS host is rewritten to the subscriber's host before token requests; otherwise the provider host is used unchanged.
  • Auto-detection of the BTP tenant API base URI from the IAS service binding (no manual wiring needed when the binding exposes it).
  • Cache is now governed by IasTenantHostCacheConfiguration (enabled / TTL / max size). Default: enabled, 1h TTL, 1000 entries. Spring Boot consumers can bind via sap.spring.security.ias.tenant-host-cache.*.

Commits

  • feat: Add IAS token flow support with tenant host resolution
  • refactor: Auto-detect btp-tenant-api from IAS service binding
  • feat: Make IAS tenant host cache configurable

Test plan

  • mvn -pl token-client test is green (17 IAS-tenant-host tests pass locally)
  • mvn -pl spring-security compile succeeds
  • Verify against an IAS binding with btp-tenant-api set: subscriber tenant token request hits subscriber subdomain
  • Verify against an IAS binding without btp-tenant-api set: falls back to provider host (no resolver constructed)
  • Verify Spring Boot binding: setting sap.spring.security.ias.tenant-host-cache.enabled=false skips caching and every resolve hits the BTP API
  • Verify cache eviction by TTL with a short ttl value

Introduces IasTokenFlows as the IAS counterpart to XsuaaTokenFlows,
providing builder-pattern APIs for client credentials and JWT bearer
token flows against SAP Identity Authentication Service.

Key additions:
- IasTokenFlows: entry point with clientCredentialsTokenFlow() and
  jwtBearerTokenFlow() builders
- IasClientCredentialsTokenFlow: supports app_tid, resource URN,
  token_format parameters for multi-tenant service-to-service tokens
- IasJwtBearerTokenFlow: supports user token exchange with the same
  IAS-specific parameters
- IasDefaultEndpoints: IAS endpoint provider (/oauth2/token,
  /oauth2/authorize, /oauth2/certs) with subdomain replacement
- IasTenantHostResolver: dynamic subscriber subdomain resolution via
  BTP tenant API (/sap/rest/tenantLoginInfo) with in-memory caching
IasTokenFlows.fromConfiguration() now automatically reads the
'btp-tenant-api' property from the OAuth2ServiceConfiguration.
If present, tenant host resolution is enabled transparently.

Also adds WARN logging when app_tid is set but no resolver is
configured, guiding users to add the property to their binding.
Replace the unbounded ConcurrentHashMap in IasTenantHostResolver with a
Caffeine cache governed by IasTenantHostCacheConfiguration (enabled, ttl,
maxSize). Add Spring properties binding under
sap.spring.security.ias.tenant-host-cache for Spring Boot consumers.
- Add 4.1.0 CHANGELOG entry covering the IAS token flows API
  (IasTokenFlows, IasClientCredentialsTokenFlow, IasJwtBearerTokenFlow)
  and the tenant host resolution with its expireAfterWrite cache.
- Extend token-client/README.md with a new "IAS Token Flows API usage"
  section that mirrors the structure of the XSUAA flows: initialization
  via fromConfiguration, the two flow builders, multi-tenant subscriber
  host resolution, cache behaviour, and Spring Boot configuration via
  sap.spring.security.ias.tenant-host-cache.*.
- Add IasRefreshTokenFlow (grant_type=refresh_token) and expose it via
  IasTokenFlows#refreshTokenFlow(). Supports the same appTid-based
  subscriber host resolution as the other two flows.
- Tighten the Javadoc and README descriptions of the existing flows: the
  difference between clientCredentials and jwtBearer is "no end-user
  context" vs "preserves user identity", not "service-to-service vs user
  propagation" (both can be app-to-app).
- Note in README and IasTokenFlows Javadoc that IAS does not offer a
  resource owner password credentials grant, so there is no password
  flow builder.
- Extend the 4.1.0 CHANGELOG entry with the refresh flow and the
  explicit grant_type for each flow.
…password-flow note

Split the IAS additions into two packages to mirror the xsuaa layout:
- ias.client: IasDefaultEndpoints, IasTenantHostResolver, IasTenantHostCacheConfiguration
- ias.tokenflows: IasTokenFlows entry point and the three flow builders

Also remove the "IAS does not offer a resource owner password credentials grant"
sentence from README and Javadoc: the IAS OIDC discovery document advertises
`password` as a supported grant. We still don't ship a password flow (ROPC is
deprecated by OAuth 2.1 and an anti-pattern), but we shouldn't claim the server
rejects it.
Signed-off-by: NiklasHerrmann21 <niklas.herrmann01@sap.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant